<?php
/**
 * Short description for file
 *
 * Long description for file (if any)...
 *
 * LICENSE: LGPL
 *
 * @category   Sabai
 * @package    Sabai_Response
 * @copyright  Copyright (c) 2006 myWeb Japan (http://www.myweb.ne.jp/)
 * @license    http://opensource.org/licenses/lgpl-license.php GNU LGPL
 * @version    CVS: $Id: Web.php 239 2008-03-07 08:39:10Z mikhail.miguel $
 * @link
 * @since      File available since Release 0.1.1
*/

/**
 * Sabai_Response
 */
require 'Sabai/Response.php';

/**
 * Short description for class
 *
 * Long description for class (if any)...
 *
 * @category   Sabai
 * @package    Sabai_Response
 * @copyright  Copyright (c) 2006 myWeb Japan (http://www.myweb.ne.jp/)
 * @author     Kazumi Ono <onokazu@gmail.com>
 * @license    http://opensource.org/licenses/lgpl-license.php GNU LGPL
 * @version    CVS: $Id: Web.php 239 2008-03-07 08:39:10Z mikhail.miguel $
 * @link
 * @since      Class available since Release 0.1.1
 */
class Sabai_Response_Web extends Sabai_Response
{
    /**
     * @var Sabai_Template
     * @access protected
     */
    var $_tpl;
    var $_layoutURL;
    var $_layoutDir;
    var $_layoutFile;
    var $_partial = false;
    var $_contentType = 'text/html';
    var $_charset;
    var $_jsHead;
    var $_jsFoot;
    var $_jsFiles;
    var $_css;
    var $_cssFiles;
    var $_htmlHead = array();
    var $_pageTitle;

    function Sabai_Response_Web(&$tpl, $layoutURL, $layoutDir, $layoutFile = null)
    {
        $this->_tpl =& $tpl;
        $this->_layoutURL = $layoutURL;
        $this->_layoutDir = $layoutDir;
        $this->_layoutFile = !empty($layoutFile) ? $layoutFile : basename($_SERVER['SCRIPT_FILENAME'], '.php') . '.html';
        $this->_charset = SABAI_CHARSET;
        $this->addCSSFile($this->_layoutURL . '/css/screen.css');
        $this->addCSSFile($this->_layoutURL . '/css/print.css', 'print');
    }

    function addTemplateDir($dir)
    {
        $this->_tpl->addTemplateDir($dir);
    }

    function setPartial($partial)
    {
    	$this->_partial = (bool)$partial;
    }

    function setContentType($contentType)
    {
        $this->_contentType = $contentType;
    }

    function setCharset($charset)
    {
        $this->_charset = $charset;
    }

    function _sendError($errorMsg, $errorURL)
    {
    	if ($this->_partial) {
            header('status: 400');
            header('HTTP/1.0 400 Bad Request');
            header(sprintf('Content-type: %s; charset=%s', $this->_contentType, $this->_charset));
            _h($errorMsg);
    	} else {
    	    if (!empty($errorMsg)) {
        	   $this->addFlash($errorMsg, true);
    	    }
        	$url = is_array($errorURL) ? Sabai_URL::getByArray($errorURL) : $errorURL;
        	header('Location: ' . str_replace(array('&amp;', "\r", "\n"), array('&'), $url));
    	}
    }

    function _sendSuccess($successMsg, $successURL)
    {
        if ($this->_partial) {
            header(sprintf('Content-type: %s; charset=%s', $this->_contentType, $this->_charset));
            _h($successMsg);
        } else {
    	    if (!empty($successMsg)) {
        	   $this->addFlash($successMsg);
    	    }
        	$url = is_array($successURL) ? Sabai_URL::getByArray($successURL) : $successURL;
        	header('Location: ' . str_replace(array('&amp;', "\r", "\n"), array('&'), $url));
    	}
    }

    function _sendContent($contentNames, $vars)
    {
        $vars['LAYOUT_URL'] = $this->_layoutURL;
        $vars['CSS'] = $this->_getCSSHTML();
        list($vars['JS'], $vars['JS_HEAD'], $vars['JS_FOOT']) = $this->_getJSHTML();
        $vars['HTML_HEAD'] = implode("\n", $this->_htmlHead);
        $vars['PAGE_TITLE'] = isset($this->_pageTitle) ? $this->_pageTitle : false;
        header(sprintf('Content-type: %s; charset=%s', $this->_contentType, $this->_charset));
        if ($this->_partial) {
        	$this->_sendTemplateContent($contentNames, $vars);
        } else {
        	$this->_sendLayoutContent($contentNames, $vars);
        }
    }

    function send()
    {
        if ($this->_charset != SABAI_CHARSET) {
            ob_start();
            parent::send();
            echo mb_convert_encoding(ob_get_clean(), $this->_charset, SABAI_CHARSET);
        } else {
            parent::send();
        }
    }

    function _sendTemplateContent($contentNames, $vars)
    {
    	// only display the template file that was found first
        foreach ($contentNames as $content_name) {
            foreach ((array)$content_name as $_content_name) {
                if ($this->_tpl->display($_content_name . '.html', $vars)) {
                    return;
                }
            }
        }
    }

    function _sendLayoutContent($contentNames, $vars)
    {
        foreach ($contentNames as $content_name) {
            foreach ((array)$content_name as $_content_name) {
                if ($content = $this->_tpl->render($_content_name . '.html', $vars)) {
                    if ($last_slash_pos = strrpos($_content_name, '/')) {
                        $_content_name = substr($_content_name, $last_slash_pos + 1);
                    }
                    $vars['CONTENT'] = sprintf("<div id=\"%s\">\n%s\n</div>\n", h(str_replace('_', '-', $_content_name)), $content);
                    break;
                }
            }
        }
        $this->_tpl->_doDisplay($this->_layoutDir . '/' . $this->_layoutFile, $vars);
    }

    function addJSHead($js)
    {
        $this->_jsHead[0][] = $js;
    }

    function addJSHeadAjax($js)
    {
        $this->_jsHead[1][] = $js;
    }

    function addJSFoot($js)
    {
        $this->_jsFoot[] = $js;
    }

    function addJSFile($path, $foot = false)
    {
        $this->_jsFiles[$foot ? 'foot' : 'head'][$path] = $path;
    }

    function _getJSHTML()
    {
        $html = array('head' => array(), 'foot' => array());
        foreach ((array)@$this->_jsFiles as $js_where => $js_paths) {
            foreach ($js_paths as $js_path) {
                $html[$js_where][] = sprintf('<script type="text/javascript" src="%s"></script>', $js_path);
            }
        }
        if (!empty($this->_jsHead)) {
            $html['head'][] = '<script type="text/javascript">';
            if (!empty($this->_jsHead[1])) {
                $html['head'][] = 'Ajax.Responders.register({onComplete: function() {';
                foreach ($this->_jsHead['1'] as $js) {
                    $html['head'][] = $js;
                }
                $html['head'][] = '}})';
            }
            $html['head'][] = 'Event.observe(window, "load", function() {';
            foreach ((array)@$this->_jsHead[0] as $js) {
                $html['head'][] = $js;
            }
            $html['head'][] = '});
</script>';
        }
        if (!empty($this->_jsFoot)) {
            $html['foot'][] = '<script type="text/javascript">';
            foreach ($this->_jsFoot as $js) {
                $html['foot'][] = $js;
            }
            $html['foot'][] = '</script>';
        }
        $html_head = implode("\n", $html['head']);
        $html_foot = implode("\n", $html['foot']);
        return array($html_head . $html_foot, $html_head, $html_foot);
    }

    function addCSS($css)
    {
        $this->_css[] = $css;
    }

    function addCSSFile($path, $media = 'screen')
    {
        $this->_cssFiles[$media][$path] = $path;
    }

    function _getCSSHTML()
    {
        $html = array();
        foreach ($this->_cssFiles as $css_media => $css_paths) {
            foreach ($css_paths as $css_path) {
                $html[] = sprintf('<link rel="stylesheet" type="text/css" media="%s" href="%s" />', $css_media, $css_path);
            }
        }
        if (!empty($this->_css)) {
            $html[] = '<style type="text/css">';
            foreach ($this->_css as $css) {
                $html[] = $css;
            }
            $html[] = '</style>';
        }
        return implode("\n", $html);
    }

    function addHTMLHead($head)
    {
        $this->_htmlHead[] = $head;
    }

    function setPageTitle($pageTitle)
    {
        $this->_pageTitle = $pageTitle;
    }
}